using System;
using System.Collections;

namespace sforceExplorer
{
	/// <summary>
	/// Summary description for GlobalProperties.
	/// </summary>
	public class GlobalProperties
	{
		private static string _endPoint = "";
		private static string _appServerURL = "";
		private static string _userName = "";
		private static string _password = "";
        private static string _token = "";
		private static string _clientId = "";
		private static string _proxyServer = "";
		private static string _proxyPort = "";
		private static bool _useCompression = false;
		private static bool _useProxy = false;
		private static string _sessionId = "";
		private static string _batchSize = "";
		private static bool _useSessionId = false;
		private static ArrayList _loginHistory = new ArrayList();
		private static bool _noHTTPS = false;
		private static string _userId = "";
		private static System.Int32 internalProxyPort;

		public static Int32 InternalProxyPort 
		{
			get { return internalProxyPort; } 
			set { internalProxyPort = value; }
		}
		public static string UserId 
		{
			get { return _userId; }
			set { _userId = value; }
		}
		public static bool noHTTPS
		{
			get {return _noHTTPS;}
			set {_noHTTPS = value;} 
		}
		public static ArrayList LoginHistory 
		{
			get { return _loginHistory; }
			set { _loginHistory = value; }
		}
		public static string endPoint
		{	get {return _endPoint;}
			set {_endPoint = value;} }
		public static string appServerURL
		{
				get {return _appServerURL;}
			set {_appServerURL = value;} 
		}
		public static string batchSize
		{
			get {return _batchSize;}
			set {_batchSize = value;} 
		}
		public static string sessionId
		{
				get {return _sessionId;}
			set {_sessionId = value;} 
		}
		public static string userName
		{
				get {return _userName;}
			set {_userName = value;} 
		}
		public static string password
		{
				get {return _password;}
			set {_password = value;} 
		}
        public static string token {
            get { return _token; }
            set { _token = value; }
        }
		public static string clientId
		{
				get {return _clientId;}
			set {_clientId = value;} 
		}
		public static string proxyServer
		{
				get {return _proxyServer;}
			set {_proxyServer = value;} 
		}
		public static string proxyPort
		{
				get {return _proxyPort;}
			set {_proxyPort = value;} 
		}
		public static bool useCompression
		{
			get {return _useCompression;}
			set {_useCompression = value;} 
		}
		public static bool useSessionId
		{
			get {return _useSessionId;}
			set {_useSessionId = value;} 
		}
		public static bool useProxy
		{
			get {return _useProxy;}
			set {_useProxy = value;} 
		}

		public GlobalProperties()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		private static void LoadLoginHistory() 
		{
			String appName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
			appName = appName.Split(Convert.ToChar(","))[0];
			Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\appName\loginHistory", true);
			if (rk == null)
				rk = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\sforce\" + appName + @"\loginHistory");
			string[] keyNames = rk.GetSubKeyNames();
			if (keyNames.Length > 0) 
			{
				ArrayList uc = new ArrayList();
				for (int i=0;i<keyNames.Length;i++) 
				{
					Microsoft.Win32.RegistryKey sk = rk.OpenSubKey(keyNames[i]);
					string pw = (string)sk.GetValue("password");
                    string tk = (String)sk.GetValue("token");
					if (((string)sk.GetValue("enc", "0")).Equals("1"))
						pw = decryptPassword(pw);
					uc.Add(new UserCredentials((string)sk.GetValue("userName"), pw, tk, keyNames[0], i));
				}
				LoginHistory = uc;
			}
		}


		internal static void CheckEncryption() 
		{
			string key = System.Guid.NewGuid().ToString();
			String appName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
			appName = appName.Split(Convert.ToChar(","))[0];
			Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\" + appName, true);
			if (rk != null) 
			{
				string pw = (string)rk.GetValue("password", string.Empty);
				if (!pw.Equals(string.Empty)) 
				{
					if (((string)rk.GetValue("enc", "0")).Equals("0")) 
					{
						rk.SetValue("password", encryptPassword(pw));
						rk.SetValue("enc", "1");
					}
				}
			}
			rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\" + appName + "\\loginHistory", true);
			if (rk == null)
				return;
			string[] keyNames = rk.GetSubKeyNames();
			if (keyNames.Length > 0) 
			{
				for (int i=0;i<keyNames.Length;i++) 
				{
					Microsoft.Win32.RegistryKey sk = rk.OpenSubKey(keyNames[i], true);
					string pw = (string)sk.GetValue("password");
					if (((string)sk.GetValue("enc", "0")).Equals("0")) 
					{
						sk.SetValue("password", encryptPassword(pw));
						sk.SetValue("enc", "1");
					}
				}
			}

		}
		public static void AddToLoginHistory(string username, string password, string token) 
		{
			string key = System.Guid.NewGuid().ToString();
			String appName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
			appName = appName.Split(Convert.ToChar(","))[0];
			Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\appName\loginHistory", true);
			if (rk == null)
				rk = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\sforce\" + appName + @"\loginHistory");
			string[] keyNames = rk.GetSubKeyNames();
			bool blnKeyFound = false;
			if (keyNames.Length > 0) 
			{
				for (int i=0;i<keyNames.Length;i++) 
				{
					Microsoft.Win32.RegistryKey sk = rk.OpenSubKey(keyNames[i]);
					string un = (string)sk.GetValue("userName");
					string pw = (string)sk.GetValue("password");
                    string tk = (string)sk.GetValue("token");
					if (un.ToLower().Equals(username.ToLower())) 
					{
						blnKeyFound = true;
						break;
					}
				}
			}

			if (!blnKeyFound) 
			{
				Microsoft.Win32.RegistryKey sk = rk.CreateSubKey(key);
				sk.SetValue("userName", username);
				sk.SetValue("password", encryptPassword(password));
                sk.SetValue("token", token);
				sk.SetValue("enc", "1");
				LoginHistory.Add(new UserCredentials(username, password, token, key, LoginHistory.Count + 1));
			}
		}

		public static void SaveSettings() 
		{
			String appName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
			appName = appName.Split(Convert.ToChar(","))[0];
			Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\appName", true);
			if (rk == null)
				rk = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\sforce\" + appName);
			rk.SetValue("username", userName);
			rk.SetValue("password", encryptPassword(password));
            rk.SetValue("token", token);
			rk.SetValue("enc", "1");
			rk.SetValue("endpoint", endPoint);
			rk.SetValue("clientid", clientId);
			rk.SetValue("proxyServer", proxyServer);
			rk.SetValue("proxyPort", proxyPort);
			rk.SetValue("batchSize", batchSize);
			rk.SetValue("sessionId", sessionId);
			rk.SetValue("appServerURL", appServerURL);
			rk.SetValue("internalProxyPort", internalProxyPort);

			if (noHTTPS)
				rk.SetValue("noHTTPS", "1");
			else
				rk.SetValue("noHTTPS", "0");

			if (useCompression)
				rk.SetValue("useCompression", "1");
			else
				rk.SetValue("useCompression", "0");

			if (useProxy)
				rk.SetValue("useProxy", "1");
			else
				rk.SetValue("useProxy", "0");
			
			if (useSessionId)
				rk.SetValue("useSessionId", "1");
			else
				rk.SetValue("useSessionId", "0");
		}

		public static void CheckSessionId(string url, string sessionid) 
		{
			sforce.SforceService b = new sforce.SforceService();
			b.Url = url;
			b.SessionHeaderValue = new sforce.SessionHeader();
			b.SessionHeaderValue.sessionId = sessionid;
			b.getUserInfo();
		}

		internal static string encryptPassword(string password) 
		{
			System.Diagnostics.Trace.WriteLine("ENCRYPT " + password);

			ConfigureSecurity.DataProtector dp = new ConfigureSecurity.DataProtector(ConfigureSecurity.Store.Machine);
			return Convert.ToBase64String(dp.Encrypt(System.Text.Encoding.ASCII.GetBytes(password), null));
		}
		internal static string decryptPassword(string password) 
		{
			ConfigureSecurity.DataProtector dp = new ConfigureSecurity.DataProtector(ConfigureSecurity.Store.Machine);
			string clearText = System.Text.Encoding.ASCII.GetString(dp.Decrypt(Convert.FromBase64String(password), null));
			System.Diagnostics.Trace.WriteLine("DECRYPT " + clearText);
			return clearText;
		}
		public static void GetRegistrySettings() 
		{
			String appName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
			appName = appName.Split(Convert.ToChar(","))[0];
			Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\sforce\appName", true);
			if (rk == null)
				rk = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(@"Software\sforce\" + appName);
			userName =  (string)rk.GetValue("username", "");
			password = (string)rk.GetValue("password", "");
            token = (string)rk.GetValue("token", "");
			if (password != "" && password.Length > 20)
				password = decryptPassword(password);
			endPoint = (string)rk.GetValue("endpoint", "");
			clientId = (string)rk.GetValue("clientid", "");
			proxyServer = (string)rk.GetValue("proxyServer", "");
			proxyPort = (string)rk.GetValue("proxyPort", "");
			sessionId = (string)rk.GetValue("sessionId", "");
			appServerURL = (string)rk.GetValue("appServerURL", Utility.binding.Url);
			internalProxyPort = (int)rk.GetValue("internalProxyPort", 8081);

			batchSize = (string)rk.GetValue("batchSize", "500");
			useCompression = rk.GetValue("useCompression", "0").Equals("1");
			noHTTPS = rk.GetValue("noHTTPS", "0").Equals("1");
			useProxy = rk.GetValue("useProxy", "0").Equals("1");
			useSessionId = rk.GetValue("useSessionId", "0").Equals("1");
			LoadLoginHistory();
		}

	}
}
